import React from 'react';
import { Upload, Icon, Modal, message } from 'antd';
import Cropper from 'react-cropper';
import 'cropperjs/dist/cropper.css'; // eslint-disable-line
import PropTypes from 'prop-types';

const cropperStyle = { height: 475, width: 475 };
const avatarStyle = { width: '100%' };

export default class AvatarUpload extends React.Component {
  static defaultProps = {
    onDone: () => {},
    onFail: () => {},
  };

  static propTypes = {
    onDone: PropTypes.func,
    onFail: PropTypes.func,
  };

  constructor(props) {
    super(props);
    this.cropper = React.createRef();
    this.state = {
      visible: false,
      blob: new Blob(),
      avatar: props.value,
    };
  }

  beforeUpload = file =>
    new Promise((resolve, reject) => {
      this.resovle = resolve;
      this.reject = reject;
      if (file.type.indexOf('image') < 0) {
        message.error('请上传正确的图片！');
        reject();
      } else {
        this.setState({
          visible: true,
          blob: file,
        });
      }
    });

  transformFile = file =>
    new Promise(resolve => {
      resolve(this.file || file);
    });

  handleCancel = () => {
    this.setState({
      visible: false,
    });
    this.reject();
  };

  handleOk = () => {
    this.cropper.current.getCroppedCanvas().toBlob(blob => {
      this.file = blob;
      this.resovle();
    });

    this.setState({
      visible: false,
    });
  };

  handleChange = info => {
    const { file, fileList } = info;
    const { onDone, onFail } = this.props;
    if (file.status === 'uploading') {
      this.setState({ loading: true });
      return;
    }
    if (file.status === 'done') {
      const reader = new FileReader();
      reader.addEventListener('load', () => {
        this.setState({
          avatar: reader.result,
          loading: false,
        });
        onDone();
      });
      reader.readAsDataURL(this.file);
    }

    if (file.status === 'error') {
      this.setState({
        loading: false,
      });
      if (onFail() !== false) message.error('头像上传失败！');
    }
    const { onChange } = this.props;
    if (onChange) {
      onChange({ file, fileList: fileList.slice(-1) });
    }
  };

  render() {
    const { visible, blob, avatar, loading } = this.state;
    const { value, ...uploadProps } = this.props;
    const uploadButton = <Icon type={loading ? 'loading' : 'plus'} />;

    const Avatar = avatar ? <img src={avatar} alt="avatar" style={avatarStyle} /> : uploadButton;

    return (
      <React.Fragment>
        <Upload
          {...uploadProps}
          accept="image/*"
          beforeUpload={this.beforeUpload}
          listType="picture-card"
          showUploadList={false}
          transformFile={this.transformFile}
          onChange={this.handleChange}
        >
          {loading ? uploadButton : Avatar}
        </Upload>
        <Modal
          visible={visible}
          onOk={this.handleOk}
          onCancel={this.handleCancel}
          maskClosable={false}
          closable={false}
        >
          <Cropper
            viewMode={2}
            style={cropperStyle}
            ref={this.cropper}
            src={URL.createObjectURL(blob)}
            aspectRatio={1}
            zoomable={false}
          />
        </Modal>
      </React.Fragment>
    );
  }
}
